package com.example.venue_reservation_service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.venue_reservation_service.domain.*;
import com.example.venue_reservation_service.dto.AdminSlot;
import com.example.venue_reservation_service.dto.PointDTO;
import com.example.venue_reservation_service.mapper.UserMapper;
import com.example.venue_reservation_service.service.*;
import com.example.venue_reservation_service.mapper.AdminMapper;
import com.example.venue_reservation_service.vo.AdminTime;
import com.example.venue_reservation_service.vo.Result;
import com.example.venue_reservation_service.vo.admin.AdminManage;
import com.example.venue_reservation_service.vo.admin.TypeBlock;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/**
* @author 31586
* @description 针对表【venue_admin(场地对应管理员信息表 )】的数据库操作Service实现
* @createDate 2024-12-22 18:16:00
*/
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin>
    implements AdminService{

    @Resource
    private TypeService typeService;

    @Resource
    private AdminMapper adminMapper;

    @Resource
    private ReservationService reservationService;

    @Resource
    private SlotService slotService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private BalanceService balanceService;

    @Resource
    private VenueSlotService venueSlotService;

    @Override
    public Result queryVenue(Integer userId) {
        Admin admin = getOne(Wrappers.<Admin>lambdaQuery().eq(Admin::getUserId, userId));
        List<TypeBlock> list = new ArrayList<>();
        AdminManage manage = new AdminManage();
        if (Optional.ofNullable(admin).isPresent()) {
            // 表示管理员有管理的场馆（管理员和场馆之间为一对一关系）
            Type type = typeService.getOne(Wrappers.<Type>lambdaQuery().eq(Type::getId, admin.getTypeId()));
            TypeBlock block = BeanUtil.copyProperties(type, TypeBlock.class);
            list.add(block);
            manage.setIsManage(true);
            manage.setList(list);
            return Result.ok(manage).message("查询成功");
        }
            // 表示当前管理员未配置管理场馆
            // 查看已经被管理的场馆
            QueryWrapper<Admin> wrapper = Wrappers.query();
            wrapper.select("DISTINCT type_id");
            List<Integer> ids = adminMapper.selectObjs(wrapper)
                    .stream()
                    .map(obj -> (Integer) obj)
                    .toList();
            LambdaQueryWrapper<Type> typeQueryWrapper = Wrappers.lambdaQuery();
            if (ids.size() > 0) {
                typeQueryWrapper.notIn(Type::getId, ids);
            }
            List<Type> types = typeService.list(typeQueryWrapper);
            types.forEach(item ->{
                TypeBlock block = BeanUtil.copyProperties(item, TypeBlock.class);
                list.add(block);
            });
            manage.setIsManage(false);
            manage.setList(list);
        return Result.ok(manage).message("查询成功");
    }

    @Override
    public Result addTime(AdminSlot slot) {

        List<AdminTime> times = slot.getTimes();
        // 使用 Stream API 进行排序
        List<AdminTime> timeList = times.stream()
                .sorted(Comparator.comparingInt(AdminTime::getId)).toList();

        LocalTime start = timeList.get(0).getStart();
        LocalTime end = timeList.get(timeList.size() - 1).getEnd();

        // 判断这个时间段是否被使用
        // 在预约记录表中查询是否存在记录
        int rz = reservationService.list(Wrappers.<Reservation>lambdaQuery()
                .eq(Reservation::getReservationDate, slot.getDate())
                .eq(Reservation::getVenueId, slot.getVenueId())
                .in(Reservation::getAuditStatus, 1, 2)
                .lt(Reservation::getStartTime, end)
                .gt(Reservation::getEndTime, start)).size();
        if(rz > 0){
            return Result.fail().message("该时间段下，部分场地已被使用");
        }

        // 获取当天的禁用情况
        List<Slot> list = slotService.list(Wrappers.<Slot>lambdaQuery()
                .eq(Slot::getReservationDate, slot.getDate())
                .lt(Slot::getSlotStart, end)
                .gt(Slot::getSlotEnd, start));

        // 判断是否存在交集
        for (Slot st : list) {
            List<VenueSlot> venueSlots = venueSlotService.list(Wrappers.<VenueSlot>lambdaQuery()
                    .eq(VenueSlot::getSlotId, st.getId())
                    .eq(VenueSlot::getVenueId, slot.getVenueId()));
            if(venueSlots.size() > 0){
                return Result.fail().message("该场地部分时间段已被超级管理员禁用");
            }
        }

        Slot record = new Slot();
        record.setUserId(slot.getUserId());
        record.setReservationDate(slot.getDate());
        record.setSlotStart(start);
        record.setSlotEnd(end);
        record.setAddTime(LocalDateTime.now());
        slotService.save(record);

        // 保存禁用状态
        VenueSlot venueSlot = new VenueSlot();
        venueSlot.setVenueId(slot.getVenueId());
        venueSlot.setSlotId(record.getId());
        venueSlotService.save(venueSlot);
        return Result.ok().message(start + "~" + end +"禁用成功");
    }

    @Override
    public Result selectUser(String phone) {
        if (phone == null || "".equals(phone)){
            return Result.fail().message("手机号码不能为空");
        }
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getUserPhone, phone));
        if (Optional.ofNullable(user).isEmpty()) {
            return Result.fail().message("未查询到相关用户信息");
        }
        Double aDouble = balanceService.getOne(Wrappers.<Balance>lambdaQuery()
                .eq(Balance::getUserId, user.getId()))
                .getBalance();
        user.setBalance(aDouble);
        return Result.ok(user).message("用户信息获取成功");
    }

    @Override
    public Result userPoint(PointDTO dto) {
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(User::getId, dto.getUserId()));
        if (Optional.ofNullable(user).isEmpty()) {
            return Result.fail().message("未查询到用户信息");
        }
        Balance balance = balanceService.getOne(Wrappers.<Balance>lambdaQuery()
                .eq(Balance::getUserId, user.getId()));
        if (Optional.ofNullable(balance).isEmpty()) {
            return Result.fail().message("未查询到用户账号信息");
        }

        balance.setBalance(balance.getBalance() + dto.getMoney());
        balanceService.updateById(balance);

        // 生成支付数据
        Payment payment = new Payment();
        payment.setUserId(user.getId());
        payment.setAmount(dto.getMoney());
        payment.setTime(LocalDateTime.now());
        payment.setSituation("充值");
        return Result.ok(payment).message("充值成功");
    }

    @Override
    public Result manage(Integer userId, Integer typeId) {
        Admin admin = new Admin();
        admin.setUserId(userId);
        admin.setTypeId(typeId);
        admin.setUpdateTime(LocalDateTime.now());
        save(admin);
        return Result.ok().message("场馆管理员设置成功");
    }

    @Override
    public Result cancel(Integer userId, Integer typeId) {
        remove(Wrappers.<Admin>lambdaQuery()
                .eq(Admin::getUserId, userId)
                .eq(Admin::getTypeId, typeId));
        return Result.ok().message("场馆信息移除成功");
    }
}




